package util

import (
	"iot/iot_app_server/proto"

	//"bytes"
	"common/logging"
	//"encoding/binary"
	"encoding/json"
	"errors"
	"fmt"
	//"encoding/hex"
	//"strconv"
)

const ERR_DEVICE_OFFLINE = "device offline"

//发消息给设备接口，bStore字段填0就行,返回值的第二个字段表示设备是否离线，为true表示离线
func SendMsgToDevice(device_id, topic, payload, sessionid string, bStore int) (error, bool) {
	bOffline := false

	var IsStore *MSGBUS_DOWNSTREAM.SEND_TYPE
	if bStore > 0 {
		IsStore = MSGBUS_DOWNSTREAM.SEND_TYPE_send_type_need_store.Enum()
	} else {
		IsStore = MSGBUS_DOWNSTREAM.SEND_TYPE_send_type_no_store.Enum()
	}

	data := &MSGBUS_DOWNSTREAM.RouteMsgInfo_B2B_C{
		Topic:     []byte(topic),
		Payload:   []byte(payload),
		DeviceId:  []byte(device_id),
		SessionId: []byte(sessionid),
		IsStore:   IsStore,
	}
	Code, Msg := RouteToDevice(data)

	logging.Debug("RouteToDevice Code=%+v,Msg=%+v", Code, Msg)

	if Code != 0 {
		logging.Error("RouteToDevice failed,device_id=%s,topic=%s,payload=%s", device_id, topic, payload)
		return errors.New("RouteToDevice failed"), bOffline
	}

	if Msg == ERR_DEVICE_OFFLINE {
		bOffline = true
	}
	return nil, bOffline
}

//透传给设备，等待回复；回复信息：错误码，是否离线，回复内容
func SyncPassThrough(reqPayload *PayloadInfo, topic string) (int, bool, PayloadInfo) {
	resp := PayloadInfo{}
	var bOffline bool = false
	errCode := ERR_CODE_SUCCESS

	loginfo := fmt.Sprintf(",reqPayload=%+v,topic=%s", reqPayload, topic)

	callback := func(pub *MSGBUS_DOWNSTREAM.MqttPub, err error) {

		if bOffline {
			logging.Error("SyncPassThrough bOffline" + loginfo)
			return
		}

		bOffline = false
		if err != nil {
			errCode = ERR_CODE_TIMEOUT
			logging.Error("SyncPassThrough cannot receive response from device, err = %s"+loginfo, err.Error())
		} else {
			err := json.Unmarshal(pub.Msg, &resp)
			//logging.Info("reqPayloadResponse=%+v", reqPayloadResponse)
			if err != nil {
				errCode = ERR_CODE_INVALID_DEVICE_RESPONSE
				logging.Error("SyncPassThrough invalid response,response payload=%s"+loginfo, string(pub.Msg))
				return
			}
			if resp.Code != 0 {
				errCode = ERR_CODE_DEVICE_RESPONSE_CODE
				logging.Error("SyncPassThrough device response code not zero ,pub.Msg=%+v"+loginfo, pub.Msg)
				return
			}

			logging.Info("SyncPassThrough data response = %s"+loginfo, pub.Msg)
		}
	}

	c := make(chan bool)
	err := AttachMsgHandle(reqPayload.Msgid, callback, Cfg.KafkaRequestTimeout, &c)
	if err != nil {
		errCode = ERR_CODE_SYSTEM_ERROR
		logging.Error("SyncPassThrough AttachMsgHandle() failed, err = %s"+loginfo, err.Error())
		return errCode, bOffline, resp
	}

	deviceID := reqPayload.Deviceid
	reqPayload.Applianceid = ""
	sendMsg, _ := json.Marshal(reqPayload)
	err, bOffline = SendMsgToDevice(deviceID, topic, string(sendMsg), "", 0)

	if bOffline {
		errCode = ERR_CODE_DEVICE_OFFLINE
		logging.Error("SyncPassThrough device offline" + loginfo)
		return errCode, bOffline, resp
	}

	if err != nil {
		errCode = ERR_CODE_SYSTEM_ERROR
		logging.Error("syncPassThrough SendMsgToDevice() failed, err = %s"+loginfo, err.Error())
		return errCode, bOffline, resp
	}
	// wait until callback returns
	<-c
	return errCode, bOffline, resp
}

func TransformOrder(order []byte) string{
	
	result := ""
	for _,v :=range(order){
		b := fmt.Sprintf("0x%X,",v)
		result += b
	}
	result = result[0:len(result)-1]
	result_b,_ := json.Marshal(result)
	return string(result_b)
}
